package org.teamswift.crow.rbac.common;

import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.teamswift.crow.rbac.annotation.PermissionAction;
import org.teamswift.crow.rest.common.ICrowDBService;
import org.teamswift.crow.rest.common.ICrowEntity;
import org.teamswift.crow.rest.common.ICrowIO;
import org.teamswift.crow.rest.exception.BusinessException;
import org.teamswift.crow.rest.exception.CrowErrorMessage;
import org.teamswift.crow.rest.exception.impl.DataNotFoundException;
import org.teamswift.crow.rest.provider.jpa.CrowControllerJpa;
import org.teamswift.crow.rest.result.CrowResult;
import org.teamswift.crow.rest.result.ICrowResult;
import org.teamswift.crow.rest.utils.CrowMessageUtil;
import org.teamswift.crow.rest.utils.Scaffolds;

import java.util.List;

@RestController
abstract public class CrowDestructibleController<
        ID,
        T extends ICrowEntity<ID, V>,
        V extends ICrowIO,
        D extends ICrowIO
        > extends CrowControllerJpa<ID, T, V, D> {

    @RequestMapping(method = RequestMethod.DELETE, value = "/destroy/{id}")
    @Transactional
    @Override
    @PermissionAction("DESTROY")
    public ICrowResult<?> destroy(@PathVariable ID id) {
        ICrowDBService<ID, T> provider = getCrowProvider();
        T entity = provider.findOneById(id).orElseThrow(() -> {
            throw new DataNotFoundException(CrowMessageUtil.error(CrowErrorMessage.NotFoundByID));
        });

        if(!entity.isDeleted()) {
            throw new BusinessException(CrowMessageUtil.error(CrowErrorMessage.EntityNotBeenSoftDeleted));
        }

        provider.destroy(entity);

        return CrowResult.ofSuccess("");
    }

    /**
     * @param ids
     * @return
     */
    @Override
    @RequestMapping(method = RequestMethod.DELETE, value = "/destroyBatch/{ids}")
    @Transactional
    @PermissionAction("DESTROY")
    public ICrowResult<?> destroyBatch(@PathVariable String ids) {
        List<ID> idList = Scaffolds.parseIdStringToGeneric(ids, getIdCls());

        ICrowDBService<ID, T> provider = getCrowProvider();
        int num = provider.destroyBatch(idList);

        return CrowResult.ofSuccess(num);
    }

}
